import Map from "ol/Map";
import View from "ol/View";
import Vector from "ol/layer/Vector";
import GeoJSON from "ol/format/GeoJSON";
import { TileWMS, Vector as VectorSource } from "ol/source";
import { Style, Fill, Stroke, Circle, Text } from "ol/style";
import Select from "ol/interaction/Select.js";
import { fromLonLat } from "ol/proj";
import Overlay from "ol/Overlay.js";
import { toLonLat } from "ol/proj";
import { Feature, VERSION } from "ol";
import Draw from "ol/interaction/Draw.js";
import VectorLayer from "ol/layer/Vector";
import XYZ from "ol/source/XYZ.js";
import TileLayer from "ol/layer/Tile.js";
import Graticule from "ol/layer/Graticule";
import WMTS from "ol/source/WMTS";
import WMTSTileGrid from "ol/tilegrid/WMTS";

// 绑定到地图实例
class olUtils {
  static view: View;
  static map: Map;
  static source: VectorSource;
  static vector: VectorLayer<any>;
  static drawObj: Draw;
  //天地图影像
  static td_img = new TileLayer({
    source: new XYZ({
      url: "http://t0.tianditu.gov.cn/img_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=	f679e73fcff0fa8d9b89dc052c35624b",
      projection: "EPSG:3857",
    }),
  });
  //影像注记
  static td_cia = new TileLayer({
    source: new XYZ({
      url: "http://t0.tianditu.gov.cn/cia_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cia&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=	f679e73fcff0fa8d9b89dc052c35624b",
      projection: "EPSG:3857",
    }),
  });
  //天地图矢量
  static td_vec = new TileLayer({
    source: new XYZ({
      url: "http://t0.tianditu.gov.cn/vec_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=vec&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=	f679e73fcff0fa8d9b89dc052c35624b",
      projection: "EPSG:3857",
    }),
  });
  //矢量注记
  static td_cva = new TileLayer({
    source: new XYZ({
      url: "http://t0.tianditu.gov.cn/cva_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cva&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=	f679e73fcff0fa8d9b89dc052c35624b",
      projection: "EPSG:3857",
    }),
  });
  static initOlMap() {
    // 创建地图视图
    this.view = new View({
      center: [118.99, 35], // 地图中心点经纬度
      zoom: 9, // 缩放级别
      projection: "EPSG:4326", // 地图投影
      // extent: [-20037508.34, -20037508.34, 20037508.34, 20037508.34], // 限制为 Web Mercator 的标准范围
      extent: [-180, -90, 180, 90], // wgs84坐标系
    });
    this.map = new Map({
      target: "map", // 这里的'map'是你在模板中的地图容器的id
      layers: [
        this.td_img,
        this.td_cia,
        // this.td_vec,
        // this.td_cva,
      ],
      view: this.view,
    });
    return this.map;
  }
  //添加天地图

  static addVecData() {
    //添加json
    const vectorSource: VectorSource = new VectorSource({
      url: "test.geojson",
      format: new GeoJSON(),
    });
    const defaultStyle = new Style({
      fill: new Fill({
        color: "rgba(0, 0, 0, 0.5)",
      }),
      stroke: new Stroke({
        color: "#bfa",
        width: 2,
      }),
      image: new Circle({
        radius: 7,
        fill: new Fill({
          color: "#bfa",
        }),
      }),
    });
    const vectorLayer: Vector<Feature> = new Vector({
      source: vectorSource,
      style: defaultStyle,
      zIndex: 1000, //将数据置于顶层
    });
    this.map.addLayer(vectorLayer);
  }
  static addVecBasemap() {
    this.map.removeLayer(this.td_img); // 移除影像图层
    this.map.removeLayer(this.td_cia); // 移除影像图层
    this.map.addLayer(this.td_vec);
    this.map.addLayer(this.td_cva);
  }
  static addImgBaseMap() {
    this.map.removeLayer(this.td_vec);
    this.map.removeLayer(this.td_cva);
    this.map.addLayer(this.td_img); // 添加影像图层
    this.map.addLayer(this.td_cia); // 添加影像图层
    console.log(this.map.getAllLayers);
  }

  static drawLine(map: any) {
    // 创建一个矢量图层作为绘图的目标图层
    this.source = new VectorSource({
      wrapX: false, // 关闭X轴的包裹
    });
    // 实例化矢量图层作为绘图层
    this.vector = new VectorLayer({
      source: this.source,
      style: new Style({
        stroke: new Stroke({
          color: "#bfa", // 线的颜色
          width: 10, // 线的宽度，单位是像素
        }),
        fill: new Fill({
          color: "rgba(255, 255, 255, 0.2)", // 填充颜色
        }),
      }),
    });
    map.addLayer(this.vector);
    // 创建一个绘图控件对象
    this.drawObj = new Draw({
      source: this.source,
      type: "LineString", // 绘制的几何类型
      freehand: true, // 开启自由绘制模式
      snapTolerance: 20,
      style: new Style({
        stroke: new Stroke({
          color: "#bfa", // 线的颜色
          width: 10, // 线的宽度，单位是像素
        }),
      }),
    });
    // 添加绘图控件
    map.addInteraction(this.drawObj);
  }
  static clearDraw(map: any) {
    map.removeInteraction(this.drawObj);
    this.source.clear();
  }

  static draw(type: any, map: any, isFreeHand = false) {
    this.clear(map);
    // 创建一个矢量图层作为绘图的目标图层
    this.source = new VectorSource({
      wrapX: false, // 关闭X轴的包裹
    });
    // 实例化矢量图层作为绘图层
    this.vector = new VectorLayer({
      source: this.source,
    });
    map.addLayer(this.vector);
    // 创建一个绘图控件对象
    this.drawObj = new Draw({
      source: this.source,
      type: type, // 绘制的几何类型
      freehand: isFreeHand, // 开启自由绘制
      snapTolerance: 20,
    });
    // 添加绘图控件
    map.addInteraction(this.drawObj);
  }
  static clear(map: any) {
    if (this.source || this.drawObj) {
      map.removeInteraction(this.drawObj);
      this.source.clear();
    }
    return;
  }
  //点击弹窗展示信息
  static addPopup() {
    let clickFeature: any = null;
    this.map.on("singleclick", (e) => {
      const features: any = this.map.getFeaturesAtPixel(e.pixel, {
        hitTolerance: 1,
      });
      console.log(features, "features");
      //定义弹窗样式
      let pt_style = function (_feature: any) {
        return new Style({
          image: new Circle({
            radius: 5,
            fill: new Fill({
              color: "red",
            }),
            stroke: new Stroke({
              //边界样式
              color: "black",
              width: 1,
            }),
          }),
          text: new Text({
            textAlign: "left", // 位置
            offsetX: 8, // 水平方向偏移量
            offsetY: 8, // 垂直方向偏移量
            font: "13px Microsoft YaHei", // 字体属性
            text: _feature.get("name"), // 显示内容
            fill: new Fill({
              // 字体颜色
              color: "red",
            }),
            stroke: new Stroke({
              // 字体轮廓
              color: "black",
              width: 1,
            }),
          }),
        });
      };
      if (clickFeature) {
        clickFeature.setStyle(null);
      }
      if (features.length > 0) {
        // features[0].setStyle(pt_style(features[0]));
        //设置点击的要素为clickFeature
        clickFeature = features[0];
      }
      // 创建一个div
      let div_popup;
      function createPopupDiv() {
        if (!document.getElementById("popup")) {
          div_popup = document.createElement("div");
          div_popup.id = "popup";
          div_popup.className = "popup";
          div_popup.style.cssText = "width:300px;height:150px; ...";
          document.body.appendChild(div_popup);
        } else {
          div_popup = document.getElementById("popup");
        }
      }
      createPopupDiv();
      // 创建一个overlay层
      let popup = new Overlay({
        element: document.getElementById("popup") as HTMLElement,
        autoPan: true,
        positioning: "center-left",
        offset: [10, -5],
      });

      let selectClick = new Select();
      this.map.addInteraction(selectClick);
      const that = this;
      selectClick.on("select", function (e) {
        let features = e.target.getFeatures().getArray();
        if (features.length > 0) {
          let element = popup.getElement() as HTMLElement;
          let coor = features[0].getGeometry().getCoordinates();
          //转为经纬度坐标
          const [lat, lng] = toLonLat(coor);
          let property = features[0].getProperties();
          let type = features[0].getGeometry().getType();
          let hdms =
            "<div style='width: 300px;height:150px; background-color: #fff; position: relative;'>";
          // 统一站号
          hdms +=
            "<div style='font-size: 16px; background-color: #224e93; color: #fff; padding: 8px; border-top-left-radius: 5px; border-top-right-radius: 5px;'>统一站号: JB3206xxxx</div>";
          // 卡片按钮
          hdms += "<div style='position: absolute; top: 50px; right: 8px;'>";
          hdms +=
            "<button style='background-color: #0e89f5; color: #fff; border: none; width:40px;height:40px; border-radius: 50%; cursor: pointer;'>卡片</button>";
          hdms += "</div>";
          // 卡片内容
          hdms += "<div style='padding: 10px;'>";
          hdms += "点名：" + property["name"] + "<br/>";
          hdms += "几何类型：" + type + "<br/>";
          hdms +=
            "位置：" +
            "[" +
            lat.toFixed(2) +
            "," +
            lng.toFixed(2) +
            "]" +
            "<br/>";
          // 添加按钮
          hdms += "<div style='margin-top: 10px; text-align: left;'>";
          hdms += "<a style='cursor:pointer; color:#009ad6'>站点详情</a>";
          hdms +=
            "<a style='margin-left: 10px; cursor:pointer; color:#009ad6'>监测数据</a>";
          hdms +=
            "<a style='margin-left: 10px; cursor:pointer; color:#009ad6'>进入管理</a>";
          hdms += "</div>";

          hdms += "</div></div><br/>";
          element.innerHTML = hdms;
          that.map.addOverlay(popup);
          popup.setPosition(coor);
        } else {
          that.map.removeOverlay(popup);
        }
      });
    });
  }
  //添加经纬网
  static addGraticule(map: Map) {
    const graticule = new Graticule({
      strokeStyle: new Stroke({
        color: "red", // 线条颜色和透明度
        width: 1, // 线条宽度
        lineDash: [1, 4], // 虚线样式（可选）
      }),
      showLabels: true, // 显示经纬度标签
      wrapX: false, // 是否横向重复（适用于全球地图）
    });
    graticule.setMap(map);
  }

  static addAISServer() {
    // 1. 定义瓦片网格参数（关键！）
    const resolutions = []; // 分辨率数组，需根据实际层级计算[4,7](@ref)
    for (let z = 0; z <= 14; z++) {
      resolutions[z] = 156543.03392804096 / Math.pow(2, z); // EPSG:3857 标准分辨率
    }
    const matrixIds = Array.from({ length: 15 }, (_, i) => `EPSG:3857:${i}`); // 矩阵ID格式需与GeoServer一致[8](@ref)

    // 2. 创建WMTS数据源
    const WMTSOption = {
      url: "http://localhost:8080/geoserver/gwc/service/wmts", // GeoServer WMTS入口[1](@ref)
      layer: "marineRanch:ais_data", // 工作区:图层名
      matrixSet: "EPSG:3857", // 需与GeoServer发布的矩阵集名称一致[6](@ref)
      format: "image/png",
      projection: "EPSG:3857",
      style: "",
      tileGrid: new WMTSTileGrid({
        origin: [-20037508.34, 20037508.34], // Web Mercator原点
        resolutions: resolutions,
        matrixIds: matrixIds,
        tileSize: [256, 256], // 默认瓦片尺寸
      }),
      wrapX: false, // 禁止横向循环[4](@ref)
    };
    const wmtsSource = new WMTS(WMTSOption);
    // 3. 创建WMTS图层
    const wmtsLayer = new TileLayer({
      source: wmtsSource,
    });
    //4 添加到地图
    this.map.addLayer(wmtsLayer);
  }

  //添加WMS服务
  static addWMS() {
    const source = new TileWMS({
      url: "http://localhost:8088/geoserver/js/wms",
      params: {
        LAYERS: "71bf_chl_map_20250610023452",
        VERSION: "1.1.0",
        TILED: true,
      },
      serverType: "geoserver",
    });
    const layer = new TileLayer({
      source: source,
    });
    this.map.addLayer(layer);
  }
}

export default olUtils;
